<script lang="tsx">
/**
 * 渲染函数
 */
export default {
  name: "render"
}
</script>

<script lang="tsx" setup>
import {h, resolveComponent} from "vue"
import {ElButton, ElOption} from "element-plus"
import {cloneDeep} from "lodash"

/**
 * 定义props
 */
const propsData = defineProps<{
  item: any,
  data?: any,
  reflections?: any
}>()

/**
 * 定义emit
 */
const emit = defineEmits<{
  (e: 'setData', item: { key: string, value: any }): void
  (e: string): void
}>()

/**
 * 适配renderFn函数传参
 */
const computedRender = (render: any) => {
  return render(propsData.data)
}

/**
 * 渲染函数
 */
function render({item}: any) {
  const {eType, prop, props, optionsData} = item
  const Type = resolveComponent(eType)

  const renderComponents = eType === "el-button"
      ? () => item.label
      : eType === "el-select" && optionsData
          ? (
              (propsData.reflections?.[optionsData?.reflect] ? propsData.reflections?.[optionsData?.reflect] : optionsData.list).map((object: any) => {
                return h(ElOption, {
                  key: object[item.optionsData.value],
                  label: object[item.optionsData.label],
                  value: object[item.optionsData.value]
                })
              })
          )
          : eType === "el-upload"
              ? (
                  h(ElButton, {
                    type: "primary"
                  }, () => "上传文件")
              ) : null

  return h(Type, {
    modelValue: propsData?.data?.[prop],
    'onUpdate:modelValue': (value: any) => emit("setData", {key: prop, value: value}),
    ...cloneDeep(props),
    onSuccess: (value: any) => emit("setData", {key: prop, value: value}),
    onClick() {
      if (item.event) {
        emit(item.event)
      } else {
        return false
      }
    }
  }, renderComponents)
}
</script>

<template>
  <component :is="computedRender(item.renderFn)" v-if="item.renderFn"/>
  <render v-else :item="propsData.item"></render>
</template>